package com.bb.blog.security.endpoint;

import com.bb.blog.security.common.OauthKeys;
import com.bb.blog.security.model.BbUserDetail;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.endpoint.FrameworkEndpoint;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

@FrameworkEndpoint
public class IntrospectEndpoint {
    TokenStore tokenStore;

    IntrospectEndpoint(TokenStore tokenStore) {
        this.tokenStore = tokenStore;
    }

    @PostMapping("/introspect")
    @ResponseBody
    public Map<String, Object> introspect(@RequestParam("token") String token) {
        OAuth2AccessToken accessToken = this.tokenStore.readAccessToken(token);
        Map<String, Object> attributes = new HashMap<>();
        if (accessToken == null || accessToken.isExpired()) {
            attributes.put(OauthKeys.ACTIVE, false);
            return attributes;
        }

        OAuth2Authentication authentication = this.tokenStore.readAuthentication(token);

        BbUserDetail userDetail = (BbUserDetail) authentication.getUserAuthentication().getPrincipal();
        // todo 字段名放在常量里

        String systemId = authentication.getOAuth2Request().getClientId();
        attributes.put(OauthKeys.ACTIVE, true);
        attributes.put(OauthKeys.EXP, accessToken.getExpiration().getTime());
        attributes.put(OauthKeys.SCOPE, accessToken.getScope().stream().collect(Collectors.joining(" ")));
        attributes.put(OauthKeys.SUB, authentication.getName());
        attributes.put(OauthKeys.USER_ID,userDetail.getUser().getId()) ;
        attributes.put(OauthKeys.AUTH, authentication.getAuthorities().stream()
            .filter(a-> a.getAuthority().startsWith(systemId.toUpperCase()))
            .map(a-> a.getAuthority().substring(systemId.length())).collect(Collectors.toList()));

        return attributes;
    }
}
